<template>
  <audio :src="notification" controls ref="notificationElement" class="d-none" id="notification"></audio>

  <div class="h-100 d-flex w-100">
    <div class="h-100 d-flex flex-column" style="flex: 1 1 auto">
      <div class="container-custom" @contextmenu.prevent>
        <div class="msg_wrapper" id="msg-wrapper" ref="msgWrapper">
          <div class="w-100 pb-3" style="padding-left: 0">
            <div v-for="(val, index) of chat_history">
              <Message ref="_MESSAGE"
                       :key="val.id+'-'+chatId"
                       :chat_data=chat_history
                       :msgIndex=index
                       :msgInfo=val
                       :chat-id=chatId
                       @onContextMenu="openContextMenu"
              />
            </div>
            <profile-card/>
            <msg-context-menu @editMessage="handleEditMsg" @deleteMsg="handleMsgDelete" :msgInfo="msgInfoToMenu"/>
          </div>
        </div>
        <div id="msg_badge" ref="msg_badge"><font-awesome-icon :icon="['fas', 'angles-down']" /></div>
      </div>
      <MsgInput :chat-id="chatId" @sending-msg="sendingMsg"/>
    </div>

    <GroupMemberList/>
    <profile-card-in-chat />
  </div>

</template>

<script setup>
import 'vue3-emoji-picker/css'
import {useRoute} from 'vue-router';
import Message from "@/pages/chat/components/Message.vue";
import notification from '@/assets/sound/notification.mp3'
import { useSocket } from "@/socket.js";
import {nextTick, onMounted, onUnmounted, ref, watch} from "vue";
import {userStore} from "@/stores/userStore.js";
import {fetchMsgApi} from "@/api/message.js";
import MsgContextMenu from "@/components/MsgContextMenu.vue";
import {messageService} from "@/service/messageService.js";
import 'animate.css'
import {FontAwesomeIcon} from "@fortawesome/vue-fontawesome";
import ProfileCard from "@/components/ProfileCard.vue";
import GroupMemberList from "@/pages/chat/aside/GroupMemberList.vue";
import MsgInput from "@/pages/chat/components/MsgInput.vue";
import ProfileCardInChat from "@/pages/chat/aside/ProfileCardInChat.vue";
const msgInfoToMenu = ref(null)
const _MESSAGE = ref()
const msgOffset = ref(0)
const route = useRoute();
const chatId = ref('')
const groupId = ref('')
const userAction = userStore()
const chat_history = ref()
const msgWrapper = ref()
const msg_badge = ref()
const notificationElement = ref()

const handleEditMsg = (msgIndex) => {
  _MESSAGE.value[msgIndex].ex_fun()
  console.log(chat_history.value[msgIndex])
}

const handleMsgDelete = async (msg) => {
  const res = messageService().deleteMsg(msg.msgInfo.id, chatId.value)
  if (!res) return void 0
  chat_history.value = chat_history.value.filter((item)=> item.id !== msg.msgInfo.id)
}

const sendingMsg = async (msg_obj) => {
  chat_history.value = [...chat_history.value, ...[msg_obj]]
  await scrollToBottom()
}

const openContextMenu = (val) => {
  msgInfoToMenu.value = val
}

const scrollToBottom = async () => {
  await nextTick(() => {
    setTimeout(()=> {
      msgWrapper.value.scrollTop = msgWrapper.value.scrollHeight
    }, 50)
  })
}

const newMessageHandler = async (rsp) => {
  console.log('received message')
  let scrollPosition = msgWrapper.value.scrollTop;
  let contentHeight = msgWrapper.value.scrollHeight;
  let viewportHeight = msgWrapper.value.clientHeight;
  if (scrollPosition + viewportHeight >= contentHeight * 0.9) {
    await nextTick(() => {
      scrollToBottom()
    })
  }

  msg_badge.value.style.backgroundColor = 'red'
  notificationElement.value.play()
  chat_history.value = [...chat_history.value, ...[rsp]]
}

const getGroupMsg = async () => {
  const res = await fetchMsgApi(chatId.value, msgOffset.value)
  chat_history.value = res.data
}

const socketDeleteMsgHandler = (msgInfo) => {
  console.log(msgInfo)
  chat_history.value = chat_history.value.filter((item)=> item.id !== msgInfo.msgId)
}

onMounted(async ()=>{
  if (route.name === "channel") {
    useSocket().emit("join group", route.params.chatId)
  }

  useSocket().emit("join chat", chatId.value);
  useSocket().on("chat message", newMessageHandler )
  useSocket().on("update message", updateMessageHandler)
  useSocket().on("delete message", socketDeleteMsgHandler)

  await getGroupMsg()
  msg_badge.value.addEventListener('click', () => {
    msgWrapper.value.scrollTop = msgWrapper.value.scrollHeight
  })
  msgWrapper.value.addEventListener('scroll', scrollEventHandle)
  await scrollToBottom()
})

const scrollEventHandle = async () =>{
  const scrollTop = msgWrapper.value.scrollTop;
  const scrollHeight = msgWrapper.value.scrollHeight;
  const clientHeight = msgWrapper.value.clientHeight;

  if (scrollHeight - clientHeight - scrollTop < 10) {
    msg_badge.value.style.display = 'none'
  } else {
    msg_badge.value.style.display = 'flex'
  }

  if (msgWrapper.value.scrollTop === 0) {
    console.warn('fetching more messages');
    msgOffset.value++
    const res = await fetchMsgApi(chatId.value, msgOffset.value)
    if (res.data.length !== 0) {
      chat_history.value = res.data.concat(chat_history.value);
      setTimeout(()=> {
        msgWrapper.value.scrollTop = msgWrapper.value.scrollHeight-scrollHeight
      },100)
    }
  }
}

const updateMessageHandler = (data) => {
  chat_history.value.forEach(item => {
    if(data.msgId === item.id) {
      item.text = data.content
      item.edited_at = '1'
    }
    return void 0
  })
}

// onBeforeRouteUpdate(async (to, from, next)=>{
//   useSocket().emit("leave chat", chatId.value)
//   // chatId.value = to.params.channelId?.trim() || to.params.chatId.trim()
//   msgOffset.value = 0
//   useSocket().emit("join chat", chatId.value);
//   const res = await fetchMsgApi(chatId.value, msgOffset.value)
//   chat_history.value = res.data
//   await scrollToBottom()
//   next()
// })

watch(route,async (nextRoute) => {
  useSocket().emit("leave chat", chatId.value)
  useSocket().emit("leave group", groupId.value)
  msgOffset.value = 0

  if (nextRoute.name === 'channel') {
    groupId.value = nextRoute.params.groupId?.trim()
    chatId.value = nextRoute.params.channelId?.trim()
  } else if (nextRoute.name === 'conversation') {
    groupId.value = ''
    chatId.value = nextRoute.params.dmId?.trim()
  }

  useSocket().emit("join chat", chatId.value);
  useSocket().emit("join group", groupId.value);
  const res = await fetchMsgApi(chatId.value, msgOffset.value)
  chat_history.value = res.data
  await scrollToBottom()

}, {immediate: true})

onUnmounted(()=> {
  useSocket().off('chat message', newMessageHandler)
  useSocket().off('update message', updateMessageHandler)
  useSocket().off('delete message', socketDeleteMsgHandler)
})
</script>


<style>
#msg_badge {
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: pointer;
  position: absolute;
  bottom: 10px;
  right: 16px;
  width: 25px;
  background-color: #1f6fd1;
  height: 25px;
}

.msg_wrapper {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  overflow-y: scroll;
  overflow-x: hidden;
  overflow-anchor: none;
  min-height: 0;
  flex: 1 1 auto;
}

.msg_wrapper::-webkit-scrollbar {
  width: 6px;
}
.msg_wrapper::-webkit-scrollbar-thumb {
  border-radius: 5px;
  background-color: var(--scrollbarThumb);
}
.msg_wrapper::-webkit-scrollbar {
  //background-color: red !important;
}
.container-custom {
  position: relative;
  display: flex;
  flex: 1 1 auto;
  min-height: 0;
  min-width: 0;
}
@media (max-width: 768px) {
  .list-custom span{
    display: none;
  }
}

</style>
